'use strict';

const Service = require('egg').Service;

const allCharStr = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz';
const REDIS_SHORT_CONNECTION_KEY = 'REDIS_SHORT_CONNECTION_KEY';

class ShortConnection extends Service {

  /**
   * 生成随机字符串
   * @param {Number} length 字符串长度
   */
  randomStr(length) {
    let str = '';
    for (let i = 0; i < length; i++) {
      const randomNum = Math.floor(Math.random() * allCharStr.length);
      str += allCharStr.charAt(randomNum);
    }
    return str;
  }

  async redisCreate(url, length) {

    const { redis } = this.app;
    for (let i = 0; i < 100; i++) {
      const str = this.randomStr(length);
      const redisKey = `${REDIS_SHORT_CONNECTION_KEY}_${str}`;
      const cacheLink = await redis.get(redisKey);
      if (!cacheLink) {
        const { link, overdueTime } = this.app.config.shortConnection;
        await redis.set(redisKey, url, 'EX', overdueTime);
        return `${link}/redis/${str}`;
      }
    }
    throw new Error('创建失败');
  }

  async redisGet(str) {
    const { redis } = this.app;
    const redisKey = `${REDIS_SHORT_CONNECTION_KEY}_${str}`;
    const link = await redis.get(redisKey);
    if (link) {
      this.ctx.redirect(link);
    } else {
      this.ctx.status = 404;
    }
  }

  async mongoCreate(url, length) {
    const { ShortConnection } = this.ctx.model;
    const { link } = this.app.config.shortConnection;
    // 查询是否有缓存
    const cacheModel = await ShortConnection.findWithUrl(url);
    if (cacheModel) {
      // 更新时间
      cacheModel.date = new Date();
      await cacheModel.save();
      return `${link}/mongo/${cacheModel.short}`;
    }
    for (let i = 0; i < 100; i++) {
      const shortStr = this.randomStr(length);
      const cacheModel = await ShortConnection.findWithShort(shortStr);
      if (!cacheModel) {
        const date = new Date();
        await new ShortConnection({
          short: shortStr,
          url,
          date,
        }).save();
        return `${link}/mongo/${shortStr}`;
      }
    }
    throw new Error('创建失败');
  }

  async mongoGet(id) {
    const { ShortConnection } = this.ctx.model;
    const cacheModel = await ShortConnection.findWithShort(id);
    if (cacheModel) {
      this.ctx.redirect(cacheModel.url);
    } else {
      this.ctx.status = 404;
    }
  }
}

module.exports = ShortConnection;
